水無瀬の部屋 > Programming > sample > tools > dlg > dyndlg.cpp |
---|
1: //*********************************************************
2: // プロジェクト: TOOLS::DYNDLG
3: // ファイル名: dyndlg.cpp
4: //*********************************************************
5: #define USE_STRNCPY // [unsafe]
6: #include <dlg/dyndlg.h>
7: #include <header/tooldbg.h>
8: #include <header/toolbase.h>
9: #include <header/toolsys.h>
10:
11:
12: //---------------------------------------------------------
13: // テスト関数 の 宣言
14: //---------------------------------------------------------
15: DECLARE_TESTPROC( test_dyndlg );
16:
17:
18: //---------------------------------------------------------
19: // 定数型マクロ の 定義
20: //---------------------------------------------------------
21: #define DBG_ALLOCNAME "CreateDialogTemplate"
22:
23: // 領域 byte[bufsize] は位置 word[offset] で size バイトの書込をするに十分な領域か?
24: #define IS_ENOUGH_SIZE( offset, size, bufsize ) (((((offset) * sizeof(WORD)) + (size)) <= (bufsize)))
25:
26:
27: //---------------------------------------------------------
28: // ファイルスコープ関数 の 宣言
29: //---------------------------------------------------------
30: static size_t ConstructDialogTemplate( WORD *ptr, size_t bufsize, const DLGTEMPLATEHEAD *src, const DLGTEMPLATEITEMDATA *items );
31:
32:
33: //*********************************************************
34: // CreateDialogTemplate
35: //*********************************************************
36: DLGTEMPLATE *
37: CreateDialogTemplate
38: (
39: const DLGTEMPLATEHEAD *dlg,
40: const DLGTEMPLATEITEMDATA *items
41: )
42: {
43: CALLONCE_TESTPROC( test_dyndlg ); // [テスト]
44:
45: // パラメタの仮定
46: ASSERT( IsValidDialogTemplateHead( dlg ) );
47: ASSERT( IsValidReadPtr( items, dlg->cdit * sizeof( *items ) ) );
48:
49: const size_t size = ConstructDialogTemplate( null, 0, dlg, items );
50: WORD *templ = (WORD *)malloc( size );
51: if ( !templ )
52: return null;
53:
54: VERIFY( size == ConstructDialogTemplate( templ, size, dlg, items ) );
55:
56: DBG_LOCK_ALLOCED_MEMORY( templ, DBG_ALLOCNAME ); // [DBG]
57: return reinterpret_cast<DLGTEMPLATE *>( templ );
58: }//CreateDialogTemplate
59:
60: //*********************************************************
61: // DestroyDialogTemplate
62: //*********************************************************
63: bool
64: DestroyDialogTemplate
65: (
66: DLGTEMPLATE *dlg
67: )
68: {
69: CALLONCE_TESTPROC( test_dyndlg ); // [テスト]
70:
71: DBG_UNLOCK_ALLOCED_MEMORY( dlg, DBG_ALLOCNAME ); // [DBG]
72: free( dlg );
73:
74: return true;
75: }//DestroyDialogTemplate
76:
77: //*********************************************************
78: // IsValidDialogTemplateHead
79: //*********************************************************
80: bool
81: IsValidDialogTemplateHead
82: (
83: const DLGTEMPLATEHEAD *dlg
84: )
85: {
86: CALLONCE_TESTPROC( test_dyndlg ); // [テスト]
87:
88: VALID_TEST( IsValidReadPtr( dlg, sizeof( *dlg ) ) );
89: VALID_TEST( 0 <= dlg->cdit );
90: VALID_TEST( 0 <= dlg->cx );
91: VALID_TEST( 0 <= dlg->cy );
92: VALID_TEST( 0 <= dlg->height );
93: VALID_TEST( ( dlg->font && (DS_SETFONT == (dlg->style & DS_SETFONT)))
94: || (!dlg->font && ( 0 == (dlg->style & DS_SETFONT))) );
95:
96: return true;
97: }//IsValidDialogTemplateHead
98:
99: //*********************************************************
100: // IsValidDialogTemplateItemData
101: //*********************************************************
102: bool
103: IsValidDialogTemplateItemData
104: (
105: const DLGTEMPLATEITEMDATA *item
106: )
107: {
108: CALLONCE_TESTPROC( test_dyndlg ); // [テスト]
109:
110: VALID_TEST( IsValidReadPtr( item, sizeof( *item ) ) );
111: VALID_TEST( WS_CHILD == (WS_CHILD & item->style) );
112: VALID_TEST( 0 <= item->cx );
113: VALID_TEST( 0 <= item->cy );
114:
115: return true;
116: }//IsValidDialogTemplateItemData
117:
118:
119: //******************************************************************************************************************
120: // private
121: //******************************************************************************************************************
122: static size_t DialogTemplate_AddDialogMenu( WORD *ptr, size_t bufsize, size_t offset, const wchar_t *menu );
123: static size_t DialogTemplate_AddDialogClassName( WORD *ptr, size_t bufsize, size_t offset, const wchar_t *classname );
124: static size_t DialogTemplate_AddDialogCaption( WORD *ptr, size_t bufsize, size_t offset, const wchar_t *caption );
125: static size_t DialogTemplate_AddDialogFontHeight( WORD *ptr, size_t bufsize, size_t offset, const DLGTEMPLATEHEAD *src );
126: static size_t DialogTemplate_AddDialogFontName( WORD *ptr, size_t bufsize, size_t offset, const DLGTEMPLATEHEAD *src );
127: static size_t DialogTemplate_AddTemplateHead( WORD *ptr, size_t bufsize, size_t offset, const DLGTEMPLATEHEAD *src );
128: static size_t DialogTemplate_AddControl( WORD *buf, size_t bufsize, size_t offset, const DLGTEMPLATEITEMDATA *src );
129: static size_t DialogTemplate_DoubleWordAlign( WORD *ptr, size_t bufsize, size_t offset );
130: static size_t DialogTemplate_AddWord( WORD *buf, size_t bufsize, size_t offset, WORD word );
131:
132:
133: //*********************************************************
134: // ConstructDialogTemplate()
135: // ダイアログテンプレートを構築する。
136: // buffer が null の場合は buffer に出力される バイト数 を返す。
137: // buffer が指定されていれば実際に出力した バイト数 を返す。
138: //
139: // WORD *ptr
140: // ダイアログテンプレートを受け取るバッファ
141: //
142: // size_t bufsize
143: // バッファのバイト数
144: //
145: // const DLGTEMPLATEHEAD *src
146: // ダイアログ情報構造体
147: //
148: // const DLGTEMPLATEITEMDATA *items
149: // 追加するコントロールの配列
150: //
151: // 使用例:
152: // const int size = CreateDialogTemplate( null, &dlg, items, numof( items ) );
153: // WORD *templ = (WORD *)malloc( size );
154: // if ( templ )
155: // {
156: // VERIFY( size == CreateDialogTemplate( templ, &dlg, items, numof( items ) ) );
157: //
158: // HINSTANCE hInstance = GetModuleHandle( null );
159: // DialogBoxIndirect( hInstance, reinterpret_cast<DLGTEMPLATE *>( templ ), HWND_DESKTOP, DlgProc );
160: // free( templ );
161: // }
162: //
163: //*********************************************************
164: static
165: size_t // 出力した バイト数
166: ConstructDialogTemplate
167: (
168: WORD *buffer,
169: size_t bufsize,
170: const DLGTEMPLATEHEAD *dlg,
171: const DLGTEMPLATEITEMDATA *items
172: )
173: {
174: // パラメタの仮定
175: ASSERT( IsValidDialogTemplateHead( dlg ) );
176: ASSERT( IsValidReadPtr( items, dlg->cdit * sizeof( *items ) ) );
177: ASSERT( !buffer || IsValidPtr( buffer, bufsize ) );
178: ASSERT( !buffer || (DESTROY_BUFFER( buffer, bufsize ), true) );
179:
180: // ヘッダの追加
181: size_t count = 0; // ワード単位
182: count += DialogTemplate_AddTemplateHead( buffer, bufsize, count, dlg ); // ヘッダの追加
183: count += DialogTemplate_DoubleWordAlign( buffer, bufsize, count ); // 境界整列
184:
185: // コントロールの追加
186: ASSERT( (0 == (count & 0x01)) || ( buffer && !IS_ENOUGH_SIZE(count, 1, bufsize) ) );
187: {for( int i = 0; i < dlg->cdit; ++i )
188: {
189: ASSERT( (0 == (count & 0x01)) || ( buffer && !IS_ENOUGH_SIZE(count, 1, bufsize) ) );
190: count += DialogTemplate_AddControl( buffer, bufsize, count, &items[ i ] ); // コントロールの追加
191: count += DialogTemplate_DoubleWordAlign( buffer, bufsize, count ); // 境界整列
192: ASSERT( (0 == (count & 0x01)) || ( buffer && !IS_ENOUGH_SIZE(count, 1, bufsize) ) );
193: }}
194: ASSERT( (0 == (count & 0x01)) || ( buffer && !IS_ENOUGH_SIZE(count, 1, bufsize) ) );
195:
196:
197: // ワード数 から バイト数 へ
198: const size_t bytesize = count * sizeof( *buffer );
199: ASSERT( !buffer || IS_ENOUGH_SIZE(count, 0, bufsize) );
200: ASSERT( !buffer
201: || (bytesize == ConstructDialogTemplate( null, 0, dlg, items ))
202: || (bufsize < ConstructDialogTemplate( null, 0, dlg, items )) );
203: return bytesize; // バイト数 を返す
204: }//ConstructDialogTemplate
205:
206: //*********************************************************
207: // DialogTemplate_AddTemplateHead()
208: //*********************************************************
209: static
210: size_t // 出力した ワード数
211: DialogTemplate_AddTemplateHead
212: (
213: WORD *buffer,
214: size_t bufsize,
215: size_t offset,
216: const DLGTEMPLATEHEAD *dlg
217: )
218: {
219: // パラメタの仮定
220: ASSERT( 0 == offset );
221: ASSERT( IsValidDialogTemplateHead( dlg ) );
222: ASSERT( !buffer || IsValidPtr( buffer, bufsize ) );
223:
224: //
225: size_t count = 0;
226:
227: // ヘッダの設定
228: if ( buffer && IS_ENOUGH_SIZE(offset + count, sizeof( DLGTEMPLATE ), bufsize) )
229: {
230: MakeDialogTemplate
231: (
232: reinterpret_cast<DLGTEMPLATE *>( buffer ),
233: dlg->cdit,
234: dlg->dwExtendedStyle,
235: dlg->style,
236: dlg->x,
237: dlg->y,
238: dlg->cx,
239: dlg->cy
240: );
241: }
242:
243: //
244: if ( !buffer || IS_ENOUGH_SIZE(offset + count, sizeof( DLGTEMPLATE ), bufsize) )
245: {
246: //
247: COMPILE_ASSERT( 0 == (sizeof( DLGTEMPLATE ) % sizeof( *buffer )) );
248: count += sizeof( DLGTEMPLATE ) / sizeof( *buffer );
249: ASSERT( !buffer || ((buffer + offset + count) == ((WORD *)(((DLGTEMPLATE *)(buffer + offset)) + 1))) );
250: }
251:
252: // 挿入される順番は意味を持つ
253: count += DialogTemplate_AddDialogMenu( buffer, bufsize, offset + count, dlg->menu ); // メニュー の設定
254: count += DialogTemplate_AddDialogClassName( buffer, bufsize, offset + count, dlg->classname ); // クラス名 の設定
255: count += DialogTemplate_AddDialogCaption( buffer, bufsize, offset + count, dlg->caption ); // タイトル の設定
256: count += DialogTemplate_AddDialogFontHeight( buffer, bufsize, offset + count, dlg ); // フォント・サイズ の設定
257: count += DialogTemplate_AddDialogFontName( buffer, bufsize, offset + count, dlg ); // フォント名 の設定
258:
259: ASSERT( !buffer || IS_ENOUGH_SIZE(offset + count, 0, bufsize) );
260: return count;
261: }//DialogTemplate_AddTemplateHead
262:
263:
264: //******************************************************************************************************************
265: //
266: //******************************************************************************************************************
267: static size_t DialogTemplate_SetResourceID( WORD *buf, size_t bufsize, size_t offset, WORD wID );
268: static size_t DialogTemplate_AddString( WORD *buf, size_t bufsize, size_t offset, const wchar_t *text );
269:
270:
271: //*********************************************************
272: // DialogTemplate_AddDialogMenu()
273: // ダイアログテンプレートに メニュー を追加する。
274: // buffer が null の場合は buffer に出力されるはずの ワード数 を返す。
275: // buffer が指定されていれば実際に出力した ワード数 を返す。
276: //
277: // WORD *buffer
278: //
279: // size_t offset
280: // メニュー の 書込位置
281: //
282: // const wchar_t *menu
283: // 書き込む メニュー
284: //
285: //*********************************************************
286: static
287: size_t // 追加した ワード数 を返す
288: DialogTemplate_AddDialogMenu
289: (
290: WORD *buffer,
291: size_t bufsize,
292: size_t offset,
293: const wchar_t *menu
294: )
295: {
296: // パラメタの仮定
297: ASSERT( !buffer || IS_ENOUGH_SIZE(offset, 0, bufsize) );
298: ASSERT( !buffer || IsValidPtr( buffer, bufsize ) );
299:
300: if ( !menu )
301: return DialogTemplate_AddWord( buffer, bufsize, offset, 0 );
302: else if ( IS_INTRESOURCE( menu ) )
303: return DialogTemplate_SetResourceID( buffer, bufsize, offset, LOWORD( menu ) );
304: else
305: return DialogTemplate_AddString( buffer, bufsize, offset, menu );
306: }//DialogTemplate_AddDialogMenu
307:
308: //*********************************************************
309: // DialogTemplate_AddDialogClassName()
310: // ダイアログテンプレート に クラス名 を指定する。
311: // buffer が null の場合は buffer に出力されるはずの ワード数 を返す。
312: // buffer が指定されていれば実際に出力した ワード数 を返す。
313: //
314: // WORD *buffer
315: //
316: // size_t offset
317: // クラス名 の 書込位置
318: //
319: // const wchar_t *classname
320: // 書き込む クラス名
321: //
322: //*********************************************************
323: static
324: size_t // 追加した ワード数 を返す
325: DialogTemplate_AddDialogClassName
326: (
327: WORD *buffer,
328: size_t bufsize,
329: size_t offset,
330: const wchar_t *classname
331: )
332: {
333: // パラメタの仮定
334: ASSERT( !buffer || IS_ENOUGH_SIZE(offset, 0, bufsize) );
335: ASSERT( !buffer || IsValidPtr( buffer, bufsize ) );
336:
337: if ( !classname )
338: return DialogTemplate_AddWord( buffer, bufsize, offset, 0 );
339: else if ( IS_INTRESOURCE( classname ) )
340: return DialogTemplate_SetResourceID( buffer, bufsize, offset, LOWORD( classname ) );
341: else
342: return DialogTemplate_AddString( buffer, bufsize, offset, classname );
343: }//DialogTemplate_AddDialogClassName
344:
345: //*********************************************************
346: // DialogTemplate_AddDialogCaption()
347: // ダイアログテンプレートに タイトル を追加する。
348: // buffer が null の場合は buffer に出力されるはずの ワード数 を返す。
349: // buffer が指定されていれば実際に出力した ワード数 を返す。
350: //
351: // WORD *buffer
352: //
353: // int offset
354: // タイトル文字列 の 書込位置
355: //
356: // const wchar_t *caption
357: // 書き込む タイトル文字列
358: //
359: //*********************************************************
360: static
361: size_t // 追加した ワード数 を返す
362: DialogTemplate_AddDialogCaption
363: (
364: WORD *buffer,
365: size_t bufsize,
366: size_t offset,
367: const wchar_t *caption
368: )
369: {
370: // パラメタの仮定
371: ASSERT( !buffer || IS_ENOUGH_SIZE(offset, 0, bufsize) );
372: ASSERT( !buffer || IsValidPtr( buffer, bufsize ) );
373:
374: return DialogTemplate_AddString( buffer, bufsize, offset, (!caption ? L"" : caption) );
375: }//DialogTemplate_AddDialogCaption
376:
377: //*********************************************************
378: // DialogTemplate_AddDialogFontHeight()
379: // ダイアログテンプレートに フォントの高さ を追加する。
380: // buffer が null の場合は buffer に出力されるはずの ワード数 を返す。
381: // buffer が指定されていれば実際に出力した ワード数 を返す。
382: //
383: // WORD *buffer
384: //
385: // int offset
386: // 高さ の 書込位置
387: //
388: // const DLGTEMPLATE_t *src
389: //
390: //*********************************************************
391: static
392: size_t // 追加した ワード数 を返す
393: DialogTemplate_AddDialogFontHeight
394: (
395: WORD *buffer,
396: size_t bufsize,
397: size_t offset,
398: const DLGTEMPLATEHEAD *src
399: )
400: {
401: // パラメタの仮定
402: ASSERT( !buffer || IS_ENOUGH_SIZE(offset, 0, bufsize) );
403: ASSERT( !buffer || IsValidPtr( buffer, bufsize ) );
404: ASSERT( IsValidReadPtr( src, sizeof( *src ) ) );
405:
406: if ( !src->font )
407: return 0;
408:
409: return DialogTemplate_AddWord( buffer, bufsize, offset, src->height );
410: }//DialogTemplate_AddDialogFontHeight
411:
412: //*********************************************************
413: // DialogTemplate_AddDialogFontName()
414: // ダイアログテンプレートに フォント名 を追加する。
415: // buffer が null の場合は buffer に出力されるはずの ワード数 を返す。
416: // buffer が指定されていれば実際に出力した ワード数 を返す。
417: //
418: // WORD *buffer
419: //
420: // int offset
421: // フォント名 の 書込位置
422: //
423: // const DLGTEMPLATE_t *src
424: //
425: //*********************************************************
426: static
427: size_t // 追加した ワード数 を返す
428: DialogTemplate_AddDialogFontName
429: (
430: WORD *buffer,
431: size_t bufsize,
432: size_t offset,
433: const DLGTEMPLATEHEAD *src
434: )
435: {
436: // パラメタの仮定
437: ASSERT( !buffer || IS_ENOUGH_SIZE(offset, 0, bufsize) );
438: ASSERT( !buffer || IsValidPtr( buffer, bufsize ) );
439: ASSERT( IsValidReadPtr( src, sizeof( *src ) ) );
440:
441: if ( !src->font )
442: return 0;
443:
444: return DialogTemplate_AddString( buffer, bufsize, offset, src->font );
445: }//DialogTemplate_AddDialogFontName
446:
447:
448: //******************************************************************************************************************
449: //
450: //******************************************************************************************************************
451: static size_t DialogTemplate_AddControlClassName( WORD *ptr, size_t bufsize, size_t offset, const wchar_t *classname );
452: static size_t DialogTemplate_AddControlText( WORD *ptr, size_t bufsize, size_t offset, const wchar_t *text );
453:
454:
455: //*********************************************************
456: // DialogTemplate_AddControl()
457: // ダイアログテンプレートに コントロール を追加する。
458: // buffer が null の場合は buffer に出力されるはずの ワード数 を返す。
459: // buffer が指定されていれば実際に出力した ワード数 を返す。
460: //
461: // WORD *buffer
462: //
463: // int offset
464: // コントロール の 書込位置
465: //
466: // const DLGITEMTEMPLATE_t *src
467: // 書き込む コントロール の情報を記述した構造体
468: //
469: //*********************************************************
470: static
471: size_t // 追加した ワード数 を返す
472: DialogTemplate_AddControl
473: (
474: WORD *buffer,
475: size_t bufsize,
476: size_t offset,
477: const DLGTEMPLATEITEMDATA *src
478: )
479: {
480: // パラメタの仮定
481: ASSERT( IsValidDialogTemplateItemData( src ) );
482: ASSERT( !buffer || IS_ENOUGH_SIZE(offset, 0, bufsize) );
483: ASSERT( (0 == (offset & 0x01)) || ( buffer && !IS_ENOUGH_SIZE(offset, 1, bufsize) ) );
484:
485: //
486: size_t count = 0;
487:
488: // ヘッダの設定
489: if ( buffer && IS_ENOUGH_SIZE(offset, sizeof( DLGITEMTEMPLATE ), bufsize) )
490: {
491: WORD *ptr = (buffer ? buffer + offset : null);
492: MakeDialogItemTemplate
493: (
494: reinterpret_cast<DLGITEMTEMPLATE *>( ptr ),
495: src->id,
496: src->dwExtendedStyle,
497: src->style | WS_CHILD,
498: src->x,
499: src->y,
500: src->cx,
501: src->cy
502: );
503: }
504:
505: //
506: if ( !buffer || IS_ENOUGH_SIZE(offset, sizeof( DLGITEMTEMPLATE ), bufsize) )
507: {
508: COMPILE_ASSERT( 0 == (sizeof( DLGITEMTEMPLATE ) % sizeof( *buffer )) );
509: count += sizeof( DLGITEMTEMPLATE ) / sizeof( *buffer );
510: }
511:
512: // 挿入される順番は意味を持つ
513: count += DialogTemplate_AddControlClassName( buffer, bufsize, offset + count, src->classname ); // クラス名 の設定
514: count += DialogTemplate_AddControlText( buffer, bufsize, offset + count, src->text ); // テキスト の設定
515: count += DialogTemplate_AddWord( buffer, bufsize, offset + count, 0 ); // 未使用のパラメタ
516:
517: ASSERT( !buffer || IS_ENOUGH_SIZE(offset + count, 0, bufsize) );
518: return count;
519: }//DialogTemplate_AddControl
520:
521: //*********************************************************
522: // DialogTemplate_AddControlClassName()
523: // ダイアログテンプレートに コントロールのクラス名 を追加する。
524: // buffer が null の場合は buffer に出力されるはずの ワード数 を返す。
525: // buffer が指定されていれば実際に出力した ワード数 を返す。
526: //
527: // WORD *buffer
528: //
529: // int offset
530: // クラス名 の 書込位置
531: //
532: // const wchar_t *classname
533: // 書き込む クラス名
534: //
535: //*********************************************************
536: static
537: size_t // 追加した ワード数 を返す
538: DialogTemplate_AddControlClassName
539: (
540: WORD *buffer,
541: size_t bufsize,
542: size_t offset,
543: const wchar_t *classname
544: )
545: {
546: // パラメタの仮定
547: ASSERT( !buffer || IS_ENOUGH_SIZE(offset, 0, bufsize) );
548: ASSERT( !buffer || IsValidPtr( buffer, bufsize ) );
549:
550: if ( IS_INTRESOURCE( classname ) )
551: return DialogTemplate_SetResourceID( buffer, bufsize, offset, LOWORD( classname ) );
552:
553: return DialogTemplate_AddString( buffer, bufsize, offset, classname );
554: }//DialogTemplate_AddControlClassName
555:
556: //*********************************************************
557: // DialogTemplate_AddControlText()
558: // ダイアログテンプレートに コントロール・テキスト を追加する。
559: // buffer が null の場合は buffer に出力されるはずの ワード数 を返す。
560: // buffer が指定されていれば実際に出力した ワード数 を返す。
561: //
562: // WORD *buffer
563: //
564: // int offset
565: // テキスト の 書込位置
566: //
567: // const wchar_t *text
568: // 書き込む テキスト
569: //
570: //*********************************************************
571: static
572: size_t // 追加した ワード数 を返す
573: DialogTemplate_AddControlText
574: (
575: WORD *buffer,
576: size_t bufsize,
577: size_t offset,
578: const wchar_t *text
579: )
580: {
581: // パラメタの仮定
582: ASSERT( !buffer || IS_ENOUGH_SIZE(offset, 0, bufsize) );
583: ASSERT( !buffer || IsValidPtr( buffer, bufsize ) );
584:
585: if ( !text )
586: return DialogTemplate_AddString( buffer, bufsize, offset, L"" );
587: else if ( IS_INTRESOURCE( text ) )
588: return DialogTemplate_SetResourceID( buffer, bufsize, offset, LOWORD( text ) );
589: else
590: return DialogTemplate_AddString( buffer, bufsize, offset, text );
591: }//DialogTemplate_AddControlText
592:
593:
594: //******************************************************************************************************************
595: //
596: //******************************************************************************************************************
597: //*********************************************************
598: // DialogTemplate_AddString()
599: // ダイアログテンプレートに 文字列 を追加する。
600: // buffer が null の場合は buffer に出力されるはずの ワード数 を返す。
601: // buffer が指定されていれば実際に出力した ワード数 を返す。
602: // 出力したワード数 には文字列終端文字 '\0' を含む。
603: //
604: // WORD *buffer
605: //
606: // int offset
607: // 文字列 の 書込位置
608: //
609: // LPCWSTR string
610: // 書き込む 文字列
611: //
612: //*********************************************************
613: static
614: size_t // 追加した ワード数 を返す
615: DialogTemplate_AddString
616: (
617: WORD *buffer,
618: size_t bufsize,
619: size_t offset,
620: LPCWSTR string
621: )
622: {
623: // パラメタの仮定
624: ASSERT( !buffer || IS_ENOUGH_SIZE(offset, 0, bufsize) );
625: ASSERT( !buffer || IsValidPtr( buffer, bufsize ) );
626: ASSERT( string ); // 少なくとも null ではない
627:
628: // 関数 wcslen() の 返値 count は 文字数 です。
629: const size_t count = wcslen( string );
630: if ( buffer && IS_ENOUGH_SIZE(offset + count + 1, 0, bufsize) )
631: {
632: //
633: // 型 wchar_t が ビルトイン型 となったため 型 wchar_t への キャスト が必要になった。
634: //
635: COMPILE_ASSERT( sizeof(WORD *) == sizeof(wchar_t *) );
636: COMPILE_ASSERT( sizeof(WORD) == sizeof(wchar_t) );
637: wcsncpy( (wchar_t *)buffer + offset, string, 1 + count );
638: buffer[ offset + count ] = '\0';
639: }
640:
641: // 1 + count
642: return (!buffer || IS_ENOUGH_SIZE(offset + count + 1, 0, bufsize)) ? (1 + count) : 0 ;
643: }//DialogTemplate_AddString
644:
645: //*********************************************************
646: // DialogTemplate_SetResourceID()
647: // ダイアログテンプレートに アトム値 を追加する。
648: // buffer が null の場合は buffer に出力されるはずの ワード数 を返す。
649: // buffer が指定されていれば実際に出力した ワード数 を返す。
650: //
651: // WORD *buffer
652: //
653: // int offset
654: // アトム値 の書込位置
655: //
656: // WORD wID
657: // 書き込む アトム値
658: //
659: //*********************************************************
660: static
661: size_t // 追加した ワード数 を返す
662: DialogTemplate_SetResourceID
663: (
664: WORD *buffer,
665: size_t bufsize,
666: size_t offset,
667: WORD wID
668: )
669: {
670: // パラメタの仮定
671: ASSERT( !buffer || IS_ENOUGH_SIZE(offset, 0, bufsize) );
672: ASSERT( !buffer || IsValidPtr( buffer, bufsize ) );
673:
674: size_t count = 0;
675: count += DialogTemplate_AddWord( buffer, bufsize, offset + count, 0xFFFF );
676: count += DialogTemplate_AddWord( buffer, bufsize, offset + count, wID );
677:
678: ASSERT( !buffer || IS_ENOUGH_SIZE(offset + count, 0, bufsize) );
679: return count;
680: }//DialogTemplate_SetResourceID
681:
682: //*********************************************************
683: // DialogTemplate_AddWord()
684: // ダイアログテンプレートに ワード値 を追加する。
685: // buffer が null の場合は buffer に出力されるはずの ワード数 を返す。
686: // buffer が指定されていれば実際に出力した ワード数 を返す。
687: //
688: // WORD *buffer
689: //
690: // int offset
691: // アトム値 の書込位置
692: //
693: // WORD w
694: // 書き込む ワード値
695: //
696: //*********************************************************
697: static
698: size_t // 追加した ワード数 を返す
699: DialogTemplate_AddWord
700: (
701: WORD *buffer,
702: size_t bufsize,
703: size_t offset,
704: WORD w
705: )
706: {
707: // パラメタの仮定
708: ASSERT( !buffer || IS_ENOUGH_SIZE(offset, 0, bufsize) );
709: ASSERT( !buffer || IsValidPtr( buffer, bufsize ) );
710:
711: if ( buffer && IS_ENOUGH_SIZE(offset, sizeof( w ), bufsize) )
712: {
713: buffer[ offset ] = w;
714: }
715:
716: return (!buffer || IS_ENOUGH_SIZE(offset, sizeof( w ), bufsize)) ? 1 : 0 ;
717: }//DialogTemplate_AddWord
718:
719: //*********************************************************
720: // DialogTemplate_DoubleWordAlign()
721: //*********************************************************
722: static
723: size_t
724: DialogTemplate_DoubleWordAlign
725: (
726: WORD *buffer,
727: size_t bufsize,
728: size_t offset
729: )
730: {
731: // パラメタの仮定
732: ASSERT( !buffer || IS_ENOUGH_SIZE(offset, 0, bufsize) );
733: ASSERT( !buffer || IsValidPtr( buffer, bufsize ) );
734:
735: size_t count = 0;
736: if ( 0 != (offset & 0x01) )
737: {
738: count += DialogTemplate_AddWord( buffer, bufsize, offset + count, 0 );
739: }
740:
741: ASSERT( !buffer || IS_ENOUGH_SIZE(offset + count, 0, bufsize) );
742: ASSERT( (0 == ((offset + count) & 0x01)) || ( buffer && !IS_ENOUGH_SIZE(offset + count, 1, bufsize) ) );
743: return count;
744: }//DialogTemplate_DoubleWordAlign
745:
746:
747: //******************************************************************************************************************
748: // TEST
749: //******************************************************************************************************************
750:
751:
752: #ifdef _DEBUG // デバッグ時のみ
753:
754:
755: //*********************************************************
756: //
757: //*********************************************************
758: DEFINE_TESTPROC( test_dyndlg )
759: {
760: #define IDC_STATICICON ( 100 )
761: #define IDC_APPNAME ( 101 )
762: #define IDC_HOMEPAGE ( 102 )
763: #define IDC_SYSRESOURCE ( 103 )
764: const DLGTEMPLATEITEMDATA items[] =
765: {
766: { CTLCLS_STATIC, L"", WS_VISIBLE | WS_CHILD | SS_ICON, 0, 7, 7, 20, 21, IDC_STATICICON },
767: { CTLCLS_STATIC, L"", WS_VISIBLE | WS_CHILD | SS_LEFT, 0, 30, 7, 1, 8, IDC_APPNAME },
768: { CTLCLS_STATIC, L"", WS_VISIBLE | WS_CHILD | SS_LEFT, 0, 30, 16, 1, 8, IDC_HOMEPAGE },
769: { CTLCLS_STATIC, L"", WS_VISIBLE | WS_CHILD | SS_LEFT, 0, 30, 25, 1, 8, IDC_SYSRESOURCE },
770: { CTLCLS_BUTTON, L"OK", WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON | WS_GROUP, 0, 45, 35, 45, 14, IDOK },
771: };
772: #undef IDC_STATICICON
773: #undef IDC_APPNAME
774: #undef IDC_HOMEPAGE
775: #undef IDC_SYSRESOURCE
776:
777: //
778: DLGTEMPLATEHEAD dlg;
779: dlg.style = DS_SYSMODAL | DS_SETFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU;
780: dlg.dwExtendedStyle = 0;
781: dlg.cdit = numof( items );
782: dlg.x = 0;
783: dlg.y = 0;
784: dlg.cx = 38,
785: dlg.cy = 56;
786: dlg.classname = null;
787: dlg.caption = L"";
788: dlg.menu = null;
789: dlg.font = L"MS Pゴシック";
790: dlg.height = 9;
791:
792:
793: //---------------------------------------------------------
794: // 定数 の テスト
795: //---------------------------------------------------------
796:
797:
798: //---------------------------------------------------------
799: // ファイルスコープ関数 の テスト
800: //---------------------------------------------------------
801:
802: //
803: {
804: const size_t size = ConstructDialogTemplate( null, 0, &dlg, items );
805: WORD *templ = (WORD *)malloc( size );
806: if ( templ )
807: {
808: VERIFY( size == ConstructDialogTemplate( templ, size, &dlg, items ) );
809: free( templ );
810: }
811: }
812:
813: //
814: {
815: const size_t size = ConstructDialogTemplate( null, 0, &dlg, items );
816: WORD *templ = (WORD *)malloc( 10 + size );
817: if ( templ )
818: {
819: VERIFY( size == ConstructDialogTemplate( templ, 10 + size, &dlg, items ) );
820: free( templ );
821: }
822: }
823:
824: //
825: {
826: WORD templ[ 1 ];
827: VERIFY( sizeof(templ) >= ConstructDialogTemplate( templ, sizeof(templ), &dlg, items ) );
828: }
829:
830:
831: //---------------------------------------------------------
832: // 公開関数 の テスト
833: //---------------------------------------------------------
834: {
835: DLGTEMPLATE *templ = CreateDialogTemplate( &dlg, items );
836: if ( templ )
837: {
838: VERIFY( DestroyDialogTemplate( templ ) );
839: }
840: }
841:
842: }//
843:
844:
845: #endif // #ifdef _DEBUG
846:
847:
848: //** end **
参照:
水無瀬の部屋 > sample > tools > dlg > dyndlg.cpp |
---|
このページは cpp2web が出力しました。
水無瀬 優 postmaster@katsura-kotonoha.sakura.ne.jp
http://katsura-kotonoha.sakura.ne.jp/prog/code/tools/dlg/dyndlg_cpp.shtml